﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NFlickr.Resource;
using NFlickr.Communication;
using NFlickr.Factory;
using NFlickr.Core.Interface;
using System.Xml.Linq;
using NFlickr.Core.Search;

namespace NFlickr.Core
{

    public class Photos : RequireSignedServiceBase
    {

        //TODO: This photos search should support the requirement if the user is not logged in.
        private const string _methodName = "flickr.photos.search";

        public Photos(FlickrService service)
        {
            initialize(service);
        }


         public Photos(FlickrService service, PhotoSearch photoSearch)
        {
            initialize(service);
            PhotoSearch = photoSearch;
        }


        private void initialize(FlickrService service)
        {
            FlickrService = service;
            Frob = service.Frob;
            Token = service.Token;
        }
        public FlickrService FlickrService
        {
            get;
            internal set;
        }

        

        public Frob Frob
        {
            get;
            internal set;
        }

        public Token Token
        {
            get;
            internal set;
        }

        public override string MethodName
        {
            get { return _methodName; }
        }

        public override string TagName
        {
            get { return "photos"; }
        }

        private IList<Photo> _photoList;
        public IList<Photo> PhotoList
        {
            get
            {
                if (_photoList == null)
                {
                    if (Refresh())
                    {
                        return _photoList;
                    }
                    return null;
                }
                return _photoList;
            }
        }

        public int CurrentPage
        {
            get;
            set;
        }


        public PhotoSearch PhotoSearch
        {
            get;
            set;
        }


        public override bool Refresh()
        {

            IChannel channel = FlickrChannelFactory.CreateInstance();
            channel.Complete += new EventHandler<SendRequestCompletedEventArgs>(channel_Complete);
            channel.SignatureRequired += new NFlickr.Core.Interface.SignatureRequiredEventHandler(channel_SignatureRequired);


            Params = new Dictionary<string, string>();

            Params.Add(NFlickr.Resource.FlickrService.ApplicationKeyName, ApplicationKey);
            Params.Add(NFlickr.Resource.FlickrService.MethodKeyName, MethodName);
            Params.Add(NFlickr.Resource.FlickrService.FrobKeyName, Frob.Value);
            Params.Add("auth_token", Token.Value);

            Params.Add("tags", GetString(PhotoSearch.PhotoTags));
            Params.Add("user_id",PhotoSearch.User.UserId);

            IResult result = channel.SendRequest(FlickrServiceUrl, this);

            if (result != null && result.ResultCode == 0)
            {
                return true;
            }
            return false;
        }

        string channel_SignatureRequired(object sender, NFlickr.Core.Interface.SignatureRequiredEventArgs args)
        {
            Params.Add(NFlickr.Resource.FlickrService.SignatureKeyName, args.Singnature);
            return GetQueryString(Params);
        }

        void channel_Complete(object sender, NFlickr.Core.Interface.SendRequestCompletedEventArgs args)
        {

            args.Result = ParseResult(args.Response);
            if (args.Result.ResultCode == 0)
            {
                XElement document = XDocument.Parse(args.Response).Element("rsp");
                XElement setElement = document.Element(TagName);

                PhotoSearch.Count = GetInteger(setElement.Attribute("total").Value);
                PhotoSearch.Pages = GetInteger(setElement.Attribute("pages").Value);
                PhotoSearch.CurrentPage = GetInteger(setElement.Attribute("page").Value);
                PhotoSearch.CountPerPage = GetInteger(setElement.Attribute("perpage").Value);

                _photoList = (from photo in setElement.Elements("photo")
                          select new Photo(FlickrService)
                          {
                              PhotoId = photo.Attribute("id").Value,
                              Title = photo.Attribute("title").Value,
                              Public = GetBoolean(photo.Attribute("ispublic").Value),
                              Family=GetBoolean(photo.Attribute("isfamily").Value),
                               Friend=GetBoolean(photo.Attribute("isfriend").Value),
                              Secret = photo.Attribute("secret").Value,

                          }).ToList();

            }

        }
    }
}
